﻿using Serilog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Core.Lib.Helper
{
    /// <summary>
    /// HttpContextHelper助手类
    /// </summary>
    public static class HttpContextHelper
    {
        /// <summary>
        /// 获取HttpRequestHeader的值,值不存在返回string.Empty;
        /// </summary>
        /// <param name="httpRequest"></param>
        /// <param name="key">header key</param>
        /// <param name="isCaseSensitive">大小写敏感</param>
        /// <returns></returns>
        public static string GetHeader(this HttpRequest httpRequest, string key,bool isCaseSensitive = false)
        {
            foreach (var item in httpRequest.Headers.Keys)
            {
                Console.WriteLine($"HttpRequest.Headers[{item}] : {httpRequest.Headers[item]}");
                if (!isCaseSensitive)
                {
                    if (item.ToLower() == key.ToLower())
                    {
                        return httpRequest.Headers[item];
                    }
                }
                else
                {
                    if(item == key)
                    {
                        return httpRequest.Headers[item];
                    }
                }
            }
            return string.Empty;
        }

        /// <summary>
        /// 将HttpContext的内容输出为String
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        public static string OutputString(this HttpContext httpContext)
        {
            string res = "";
            if (httpContext != null)
            {
                StringBuilder sbRes = new StringBuilder();
                sbRes.AppendLine($"HttpRequest:\r\n{httpContext?.Request?.OutputString()}");
                sbRes.AppendLine("===== ===== ===== ===== ===== =====\r\n");
                try
                {
                    sbRes.AppendLine($"Session:\r\n{httpContext?.Session?.OutputString()}");
                    sbRes.AppendLine("===== ===== ===== ===== ===== =====\r\n");
                }
                catch
                {
                    //Todo 未启用Session会抛错
                }
                sbRes.AppendLine($"HttpOutput:\r\n{httpContext?.Response?.OutputString()}");
                sbRes.AppendLine("===== ===== ===== ===== ===== =====\r\n");
                res = sbRes.ToString();
            }
            return res;
        }

        /// <summary>
        /// 将httpResponse的内容输出为String
        /// </summary>
        /// <param name="httpResponse"></param>
        /// <returns></returns>
        public static string OutputString(this HttpResponse httpResponse)
        {
            string res = "";
            if (httpResponse != null)
            {
                //Response流不可读
                //try
                //{
                //    using (StreamReader stream = new StreamReader(httpResponse.Body))
                //    {
                //        httpResponse.Body.Seek(0, SeekOrigin.Begin);
                //        body = stream.ReadToEndAsync().GetAwaiter().GetResult();
                //    }
                //}
                //catch (Exception ex)
                //{
                //    Log.Error(ex, "将HttResponse的内容输出为String读取Body时出错");
                //}

                StringBuilder sbLog = new StringBuilder();
                sbLog.AppendLine($"StatusCode：{httpResponse.StatusCode}\r\n");
                //sbLog.AppendLine($"Content-Type：{httpResponse.ContentType}\r\n");
                //sbLog.AppendLine($"Content-Length：{httpResponse.ContentLength}\r\n");
                //sbLog.AppendLine($"Content：\r\n{body}\r\n");
                res = sbLog.ToString();
            }
            return res;
        }
         
        /// <summary>
        /// 将HttpRequest的内容输出为String
        /// </summary>
        /// <param name="httpRequest"></param>
        /// <returns></returns>
        public static string OutputString(this HttpRequest httpRequest)
        {
            string res = "";
            if (httpRequest != null) {
                string body = "";
                try
                {
                    using (StreamReader stream = new StreamReader(httpRequest.Body))
                    {
                        httpRequest.EnableBuffering();
                        httpRequest.Body.Seek(0, SeekOrigin.Begin);
                        body = stream.ReadToEndAsync().GetAwaiter().GetResult();
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(ex, "将HttpRequest的内容输出为String读取Body时出错");
                }
                StringBuilder sbRes = new StringBuilder();
                string url = "";
                if (httpRequest.IsHttps)
                {
                    url = $"https://{httpRequest.Host.Value}";
                }
                else
                {
                    url = $"http://{httpRequest.Host.Value}";
                }
                sbRes.AppendLine($"请求的Url：{url + httpRequest.GetEncodedPathAndQuery()}\r\n");                
                sbRes.AppendLine($"请求路径：{httpRequest.Method} => {url + httpRequest.Path.Value}\r\n");
                sbRes.AppendLine($"Headers：\r\n{httpRequest.Headers.OutputString()}\r\n");
                sbRes.AppendLine($"Cookies：\r\n{httpRequest.Cookies.OutputString()}\r\n");
                sbRes.AppendLine($"Content-Type：{httpRequest.ContentType}\r\n");
                sbRes.AppendLine($"Content-Length：{httpRequest.ContentLength}\r\n");
                sbRes.AppendLine($"Content：\r\n{body}\r\n");
                res = sbRes.ToString();
            }
            return res;

        }

        /// <summary>
        /// 获取HttpResponse的值,值不存在返回string.Empty;
        /// </summary>
        /// <param name="httpResponse"></param>
        /// <param name="key">header key</param>
        /// <param name="isCaseSensitive">大小写敏感</param>
        /// <returns></returns>
        public static string GetHeader(this HttpResponse httpResponse, string key, bool isCaseSensitive = false)
        {
            foreach (var item in httpResponse.Headers.Keys)
            {
                Console.WriteLine($"HttpResponse.Headers[{item}] : {httpResponse.Headers[item]}");
                if (!isCaseSensitive)
                {
                    if (item.ToLower() == key.ToLower())
                    {
                        return httpResponse.Headers[item];
                    }
                }
                else
                {
                    if (item == key)
                    {
                        return httpResponse.Headers[item];
                    }
                }
            }
            return string.Empty;
        }

        /// <summary>
        /// 将Header输出为String
        /// </summary>
        /// <param name="headerDictionary"></param>
        /// <param name="splicingOperator">拼接服</param>
        /// <returns></returns>
        public static string OutputString(this IHeaderDictionary headerDictionary,string splicingOperator = "\r\n")
        {
            List<string> resList = new List<string>();
            if (headerDictionary != null)
            {
                foreach (var item in headerDictionary)
                {
                    resList.Add($"{item.Key}:{item.Value}");
                }
            }
            return string.Join(splicingOperator, resList);
        }

        /// <summary>
        /// 将Header输出为String
        /// </summary>
        /// <param name="session"></param>
        /// <param name="splicingOperator">拼接符</param>
        /// <returns></returns>
        public static string OutputString(this ISession session, string splicingOperator = "\r\n")
        {
            string res = $"";
            if (session != null)
            {
                List<string> resList = new List<string>();
                foreach (var key in session.Keys)
                {
                    var val = session.Get(key);                    
                    resList.Add($"{key}:{System.Text.Encoding.UTF8.GetString(val)}");
                }
                string sessionString = string.Join(splicingOperator, resList);
                StringBuilder sbRes = new StringBuilder();
                sbRes.AppendLine($"Session Id:{session.Id}\r\n");                
                sbRes.AppendLine($"Session Is Available:{session.IsAvailable}\r\n");
                sbRes.AppendLine($"Session Key-Value:\r\n{sessionString}\r\n");
                res = sbRes.ToString();
            }
            return res;
        }

        /// <summary>
        /// 将RequestCookieCollection输出为String
        /// </summary>
        /// <param name="cookieCollection"></param>
        /// <param name="splicingOperator">拼接符</param>
        /// <returns></returns>
        public static string OutputString(this IRequestCookieCollection cookieCollection, string splicingOperator = "\r\n")
        {
            List<string> resList = new List<string>();
            if (cookieCollection != null)
            {
                foreach (var item in cookieCollection)
                {
                    resList.Add($"{item.Key}:{item.Value}");
                }
            }
            return string.Join(splicingOperator, resList);
        }
    }
}
